package com.nowcoder.community.util;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * @author szq
 * @create 2023-02-27 23:32
 * @description 自定义认证规则
 * AuthenticationProvider：ProviderManager 持有一组 AuthenticationProvider,每个 ProviderManager 负责一种认证
 * 委托模式：ProviderManager 将认证委托给 ProviderManager.
 */
@Component
public class AdminAuthenticationProvider implements AuthenticationProvider {

    private UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    // Authentication: 用于封装认证信息的接口，不同的实现类代表不同类型的认证信息。
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取前端表单中输入后返回的用户名、密码
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        User user = userMapper.findUserByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("账号不存在!");
        }
        // 验证密码
        password = CommunityUtil.md5(password + user.getSalt());
        if (!user.getPassword().equals(password)) {
            throw new BadCredentialsException("密码不正确!");
        }
        return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return UsernamePasswordAuthenticationToken.class.equals(aClass);
    }
}
